package cz.matasek.dbLogger.model;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * The class represents a certain date and time instant.
 *
 * @author Luboš Matásek
 */
public class DateTime {

    /**
     * Year.
     */
    private int year;
    /**
     * Month in year.
     */
    private int month;
    /**
     * Day in month.
     */
    private int day;
    /**
     * Hour in day (0-23).
     */
    private int hour;
    /**
     * Minute in hour.
     */
    private int minute;
    /**
     * Second in minute.
     */
    private int second;

    /**
     * Creates an empty <code>DateTime</code> object.
     */
    public DateTime() {
    }

    /**
     * Creates a new <code>DateTime</code> object from {@link java.util.Date}.
     * 
     * @param date date object
     */
    public DateTime(Date date) {
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);

        year = calendar.get(Calendar.YEAR);
        month = calendar.get(Calendar.MONTH) + 1; // months are indexed from zero
        day = calendar.get(Calendar.DAY_OF_MONTH);
        hour = calendar.get(Calendar.HOUR_OF_DAY);
        minute = calendar.get(Calendar.MINUTE);
        second = calendar.get(Calendar.SECOND);
    }

    /**
     * Creates a new <code>DateTime</code> object for the specified instant.
     *
     * @param year year
     * @param month month in year
     * @param day day in month
     * @param hour hour in day
     * @param minute minute in hour
     * @param second second in minute
     */
    public DateTime(int year, int month, int day, int hour, int minute, int second) {
        this.year = year;
        this.month = month;
        this.day = day;
        this.hour = hour;
        this.minute = minute;
        this.second = second;
    }

    /**
     * Checks if this <code>DateTime</code> object represent any existing date
     * and time instant. Check is done through {@link java.util.Calendar} class.
     *
     * @return <code>true</code> if date and time are valid; <code>false</code>
     * otherwise
     */
    public boolean isValid() {
        Calendar calendar = getCalendar();

        // if date is valid, values in calendar were not changed
        if (year == calendar.get(Calendar.YEAR) &&
                month == calendar.get(Calendar.MONTH) + 1 && // months are indexed from zero
                day == calendar.get(Calendar.DAY_OF_MONTH) &&
                hour == calendar.get(Calendar.HOUR_OF_DAY) &&
                minute == calendar.get(Calendar.MINUTE) &&
                second == calendar.get(Calendar.SECOND)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * Returns string representation of this <code>DateTime</code> object.
     * The string has following format <code>yyyy-MM-dd HH:mm:ss</code>
     * according to {@link java.text.SimpleDateFormat} specification.
     * 
     * @return date and time string
     */
    @Override
    public String toString() {
        SimpleDateFormat dateFormat =
                new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        return dateFormat.format(getCalendar().getTime());
    }

    /**
     * Returns {@link java.util.Calendar} object representing this
     * <code>DateTime</code> (if not valid, <code>Calendar</code> can contain
     * different date and time).
     *
     * @return {@link java.util.Calendar} object
     */
    public Calendar getCalendar() {
        return new GregorianCalendar(year, month - 1, day, hour, minute, second);
    }

    /**
     * Returns year of this <code>DateTime</code>.
     *
     * @return the year
     */
    public int getYear() {
        return year;
    }

    /**
     * Sets year of this <code>DateTime</code>.
     *
     * @param year the year to set
     */
    public void setYear(int year) {
        this.year = year;
    }

    /**
     * Returns month of this <code>DateTime</code>.
     *
     * @return the month
     */
    public int getMonth() {
        return month;
    }

    /**
     * Sets month of this <code>DateTime</code>.
     *
     * @param month the month to set
     */
    public void setMonth(int month) {
        this.month = month;
    }

    /**
     * Returns day in month of this <code>DateTime</code>.
     *
     * @return the day in month
     */
    public int getDay() {
        return day;
    }

    /**
     * Sets day in month of this <code>DateTime</code>.
     *
     * @param day the day to set
     */
    public void setDay(int day) {
        this.day = day;
    }

    /**
     * Returns hour of this <code>DateTime</code>.
     *
     * @return the hour
     */
    public int getHour() {
        return hour;
    }

    /**
     * Sets hour of this <code>DateTime</code>.
     *
     * @param hour the hour to set
     */
    public void setHour(int hour) {
        this.hour = hour;
    }

    /**
     * Returns minute of this <code>DateTime</code>.
     *
     * @return the minute
     */
    public int getMinute() {
        return minute;
    }

    /**
     * Sets minute of this <code>DateTime</code>.
     *
     * @param minute the minute to set
     */
    public void setMinute(int minute) {
        this.minute = minute;
    }

    /**
     * Returns second of this <code>DateTime</code>.
     *
     * @return the second
     */
    public int getSecond() {
        return second;
    }

    /**
     * Sets second of this <code>DateTime</code>.
     *
     * @param second the second to set
     */
    public void setSecond(int second) {
        this.second = second;
    }
}
